#include <iostream>
#include <algorithm>
#include <iterator>
#include <vector>
#include <assert.h>

#include "lambda/lambda.hpp"

using namespace night::lambda;

int main ()
{
	arg<1> fn;

	int i=1, j=2, k=3;
	int array [] = {1,2,3,4,5,6,7,8,9,0};
	int size = sizeof (array) / sizeof (*array);

	int sum = 0;
	int s = 0;

	std::for_each (array, array+size, fun (x) [ sum += x ] );
	std::for_each (array, array+size, fun (x) [ assign [s,s+x] ] );
	assert ( s == 45 );
	assert ( sum == 45 );

	std::vector<int> d ( 10, int (1) );
	std::vector<int>::iterator ii = d.begin(), ji = d.end();
	std::copy ( d.begin (), d.end (), std::ostream_iterator<int> (std::cout) );
	std::cout << std::endl;
	std::for_each ( ii, ji, x=2 );
	std::copy ( d.begin (), d.end (), std::ostream_iterator<int> (std::cout) );
	std::cout << std::endl;
	assert ( fun (x,y) [ *x += *y ] (ii,ii) == 4 );

	fun (x) [ x+= 1 ] (i);
	assert ( i == 2 );
	fun (x) [ x = 1 ] (i);

	assert ( (x+1) (i) == 2 );
	assert ( ((x+1)*y) (i,j) == 4 );
	assert ( (x-1) (i) == 0 );
	assert ( (x*2) (j) == 4 );
	assert ( (x/2) (j) == 1 );
	assert ( (x%2) (k) == 1 );
	assert ( (-x) (i) == -1 );

	assert ( (x< y) (i,j) == true );
	assert ( (x==y) (i,j) == false );
	assert ( (x!=y) (i,j) == true );
	assert ( (x> y) (i,j) == false );
	assert ( (!(x==y)) (i,j) == true );

	int v = 1;

	(v += x) (ref(1));
	assert ( v == 2 );
	(v -= x) (ref(1));
	assert ( v == 1 );
	(v *= x)(ref(10));
	assert ( v == 10);
	(v /= x) (ref(2));
	assert ( v == 5 );
	(v %= x) (ref(2));
	assert ( v == 1 );

	(x += 1) (i);
	assert ( i == 2 );
	(x -= 1) (i);
	assert ( i == 1 );
	(x *= 10)(i);
	assert ( i == 10);
	(x /= 2) (i);
	assert ( i == 5 );
	(x %= 2) (i);
	assert ( i == 1 );

}

